﻿using System;
using System.Windows.Media.Imaging;
using SomethingSpacial.CustomControls;
using SomethingSpacial.Model;
using SomethingSpacialClassLib.Web;
using System.Collections.ObjectModel;
using System.ServiceModel.DomainServices.Client;
using System.Collections.Generic;
using System.Linq;

namespace SomethingSpacial.ViewModel
{
    public class EventsViewModel : ViewModelBase
    {
        private EventModel MyModel = new EventModel();
        private SomethingSpacialContext domainContext;
        public SomethingSpacialContext DomainContext
        {
            get
            {

                if (domainContext == null)
                {
                    domainContext = new SomethingSpacialContext();
                    domainContext.PropertyChanged += new System.ComponentModel.PropertyChangedEventHandler(domainContext_PropertyChanged);
                }
                return domainContext;
            }
        }

        void domainContext_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
        {
            if (e.PropertyName == "HasChanges")
                InvokePropertyChanged("DisableSelections");
        }
        public bool DisableSelections
        {
            get { return !DomainContext.HasChanges; }
        }

        private bool eventsAreLoaded = false;
        public IEnumerable<SomethingSpacialClassLib.Web.Event> Events
        {
            get
            {
                if (!eventsAreLoaded)
                {
                    LoadEvents();
                }
                return DomainContext.Events;
            }
            //No set, it is a read-only property.
        }

        private bool locationsAreLoaded = false;
        public IEnumerable<SomethingSpacialClassLib.Web.Location> Locations
        {
            get
            {
                if (!locationsAreLoaded)
                {
                    LoadLocations();
                }
                return DomainContext.Locations;
            }
            //No set, it is a read-only property.
        }

        private Event _currentEvent;
        public Event CurrentEvent
        {
            get
            {
                return _currentEvent;
            }
            set
            {
                if (_currentEvent != null)
                    _currentEvent.PropertyChanged -= new System.ComponentModel.PropertyChangedEventHandler(currentEvent_PropertyChanged);
                _currentEvent = value;
                _currentEvent.PropertyChanged += new System.ComponentModel.PropertyChangedEventHandler(currentEvent_PropertyChanged);
                InvokePropertyChanged("CurrentEvent");
                InvokePropertyChanged("CanEditCurrentEvent");
                InvokePropertyChanged("CurrentLocation");
            }
        }

        public Location CurrentLocation
        {
            get
            {
                return Locations.Where(l => l.LOC_Id == CurrentEvent.EVT_Location).FirstOrDefault();
            }
            set
            {
                CurrentEvent.EVT_Location = value.LOC_Id;
            }
        }

        void currentEvent_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
        {
            if (e.PropertyName == "IsReadOnly")
                InvokePropertyChanged("CanEditCurrentEvent");
            else if (e.PropertyName == "EVT_Location")
                InvokePropertyChanged("CurrentLocation");

        }

        public bool CanEditCurrentEvent
        {
            get
            {
                if (CurrentEvent != null)
                    return !CurrentEvent.IsReadOnly;
                else
                    return false;
            }
        }

        public Event CreateNewEvent()
        {
            Event newEvent = new Event();
            newEvent.EVT_Id = 0;
            newEvent.EVT_Name = "New Event";
            newEvent.EVT_Location = 1;
            newEvent.EVT_RegistrationUrl = "registration.aspx";
            newEvent.EVT_Start_Date = DateTime.Now;
            newEvent.EVT_UserGroup = 1;
            newEvent.EVT_End_Date = DateTime.Now;
            newEvent.EVT_Image = "";
            CurrentEvent = newEvent;
            DomainContext.Events.Add(newEvent);
            return newEvent;
        }

        public void CommitChanges()
        {
            if (DomainContext.HasChanges)
                DomainContext.SubmitChanges();
        }
          
        #region "ViewModel Methods"

        public void LoadEvents()
        {
            DomainContext.Load<Event>(DomainContext.GetEventsQuery(), LoadBehavior.MergeIntoCurrent, EventsLoaded, null);
            eventsAreLoaded = true;
        }

        private void EventsLoaded(LoadOperation<Event> lo)
        {
            //TODO: Add error handling
        }

        public void LoadLocations()
        {
            DomainContext.Load<Location>(DomainContext.GetLocationsQuery(), LoadBehavior.MergeIntoCurrent, LocationsLoaded, null);
            locationsAreLoaded = true;
        }

        private void LocationsLoaded(LoadOperation<Location> lo)
        {
            //TODO: Add error handling
        }

        public void AddEvent(Event EventNew)
        {
            try
            {
                DomainContext.Events.Add(EventNew);
                DomainContext.SubmitChanges();
            }
            catch (Exception exc)
            {
                string message = exc.InnerException.ToString();
                System.Windows.MessageBox.Show(message);
            }
        }

        public void UpdateEvent()
        {
            DomainContext.SubmitChanges();
        }

        public void DeleteEvent(Event Event)
        {
            try
            {
                DomainContext.Events.Remove(Event);
                DomainContext.SubmitChanges();
            }
            catch (Exception exc)
            {
                string message = exc.InnerException.ToString();
                System.Windows.MessageBox.Show(message);
            }

        }   

        #endregion

        #region "ViewModel Properties"

        public BitmapImage LogoImage
        {
            get 
            { 
                BitmapImage TempImage = new BitmapImage();
                TempImage.UriSource = new Uri(MyModel.LogoImage, UriKind.RelativeOrAbsolute);
                return TempImage; 
            } 
        }

        public string TopicTitle
        {
            get { return MyModel.TopicTitle; }
            set
            {
                if (MyModel.TopicTitle != value)
                {
                    MyModel.TopicTitle = value;
                    InvokePropertyChanged("TopicTitle");
                }
            }
        }

        public string TopicDescription
        {
            get { return MyModel.TopicDescription; }
            set
            {
                if (MyModel.TopicDescription != value)
                {
                    MyModel.TopicDescription = value;
                    InvokePropertyChanged("TopicDescription");
                }
            }
        }

        public static string TwitterUrl
        {
            get { return EventModel.TwitterUrl; }
        }

        public static string RssUrl
        {
            get { return EventModel.RssUrl; }
        }

        public static string RegistrationURL
        {
            get { return EventModel.RegistrationURL; }
        }

        public static string FcbkUrl
        {
            get { return EventModel.FcbkUrl; }
        }

        public string When
        {
            get { return MyModel.When; }
            set
            {
                if (MyModel.When != value)
                {
                    MyModel.When = value;
                    InvokePropertyChanged("When");
                }
            }
        }

        public string AddressLine1
        {
            get { return MyModel.AddressLine1; }
            set
            {
                if (MyModel.AddressLine1 != value)
                {
                    MyModel.AddressLine1 = value;
                    InvokePropertyChanged("AddressLine1");
                }
            }
        }

        public string AddressLine2
        {
            get { return MyModel.AddressLine2; }
            set
            {
                if (MyModel.AddressLine2 != value)
                {
                    MyModel.AddressLine2 = value;
                    InvokePropertyChanged("AddressLine2");
                }
            }
        }

        public static string MeetingInvite
        {
            get { return EventModel.MeetingInvite; }
        }

        #endregion
    }
}
